package com.ccteam.shared.domain.artist

import android.support.v4.media.MediaMetadataCompat
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.map
import com.ccteam.fluidmusic.fluidmusic.common.MusicServiceConnectionFlow
import com.ccteam.fluidmusic.fluidmusic.media.extensions.*
import com.ccteam.model.music.BITRATE_NO
import com.ccteam.model.music.MusicVO
import com.ccteam.shared.api.MusicDataSource
import com.ccteam.shared.data.artist.ArtistDetailMusicPagingSource
import com.ccteam.shared.domain.PagingUseCase
import com.ccteam.shared.result.artist.ArtistInfoData
import com.ccteam.shared.result.music.DefaultMusicItem
import com.ccteam.shared.utils.ARTIST_SEPARATOR
import com.ccteam.shared.utils.EMPTY_STRING
import com.ccteam.shared.utils.getPlaybackStatus
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import javax.inject.Inject

/**
 * @author Xiaoc
 * @since 2021/2/20
 */
class ArtistDetailMusicUseCase @Inject constructor(
    private val musicServiceConnectionFlow: MusicServiceConnectionFlow,
    private val musicDataSource: MusicDataSource
): PagingUseCase<Pair<String?, String?>, DefaultMusicItem>(
    Dispatchers.IO
) {

    override fun execute(parameters: Pair<String?,String?>): Flow<PagingData<DefaultMusicItem>> {
        val (parentId,artistId) = parameters
        if(parentId.isNullOrEmpty() || artistId.isNullOrEmpty()){
            return flowOf(PagingData.empty())
        }
        return Pager(
            PagingConfig(pageSize = 30)
        ){
            ArtistDetailMusicPagingSource(artistId,musicDataSource)
        }.flow.map { pagingData ->
            // 将数据转换为 DefaultMusicItem
            pagingData.map { music ->
                // 将音乐加入到BrowseTree
                addMusicToBrowseTree(parentId,music)

                /**
                 * 分割成ArtistInfoData类型，其中含有歌手信息
                 */
                val artistsArray = music.artists.split(ARTIST_SEPARATOR)
                val artistInfo = if(artistsArray.size == music.artistsId.size){
                    artistsArray.mapIndexed{ index, artistName ->
                        ArtistInfoData(music.artistsId[index],artistName)
                    }
                } else {
                    emptyList()
                }
                DefaultMusicItem(music.id,music.name,music.artists,artistInfo,
                    music.albumId,music.imgUrl ?: EMPTY_STRING,music.maxBitrate,
                    playable = !music.url.isNullOrEmpty(),
                    musicServiceConnectionFlow.nowPlaying.value.getPlaybackStatus(music.id))
            }
        }
    }

    private fun addMusicToBrowseTree(parentId: String,music: MusicVO){
        if(music.maxBitrate == BITRATE_NO || music.url.isNullOrEmpty()) {
            return
        }
        musicServiceConnectionFlow.addOnlineMusicItem(
            parentId,
            MediaMetadataCompat.Builder().apply {
                id = music.id
                duration = music.duration
                title = music.name
                album = music.albumName
                albumId = music.albumId
                displayTitle = music.name
                displaySubtitle = music.albumName
                displayDescription = music.artists
                artist = music.artists
                trackNumber = music.track.toLong()
                mediaUri = music.url
                albumArtUri = music.imgUrl
                displayIconUri = music.imgUrl
            }.build()
        )
    }
}